package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.api.article.IArticleClient;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmSensitive;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.utils.common.Tess4jUtils;
import com.heima.wemedia.mapper.WmSensitiveMapper;
import com.heima.wemedia.service.WmChannelService;
import com.heima.wemedia.service.WmNewsAutoScanService;
import com.heima.wemedia.service.WmNewsService;
import com.heima.wemedia.service.WmUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;


import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {

    @Autowired
    private WmNewsService wmNewsService;
    @Autowired
    private IArticleClient articleClient;
    @Autowired
    private WmUserService wmUserService;
    @Autowired
    private WmChannelService wmChannelService;

    //完整审核
    @Async
    @Override
    public void autoScanNews(Integer id) {
        WmNews wmNews = wmNewsService.getById(id);
        if (wmNews == null) {
            throw new RuntimeException("WmNewsAutoScanServiceImpl：文章不存在");
        }
        // 获取文章内容和图片
        Map<String, Object> contentAndPictures = getContentAndPictures(wmNews);

        //自有敏感词库过滤
        boolean result = selfSensitiveScanFilter((String) contentAndPictures.get("text"),wmNews);
        if (!result){
            return;
        }

        // 审核
        boolean scanResult = aliAutoScan(contentAndPictures, wmNews);
        // 1.审核文本内容，设置文章状态
            // 2.审核图片内容，设置文章状态
        //远程调用文章服务保存文章数据
        if (!scanResult){
            return;
        }
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        articleDto.setContent(wmNews.getContent());
        articleDto.setAuthorId(wmNews.getUserId().longValue());
        WmUser wmUser = wmUserService.getById(wmNews.getUserId());
        articleDto.setAuthorName(wmUser.getName());
        WmChannel wmChannel = wmChannelService.getById(wmNews.getChannelId());
        articleDto.setChannelName(wmChannel.getName());
        articleDto.setLayout(wmNews.getType());
        articleDto.setCreatedTime(new Date());
        Long articleId = wmNews.getArticleId();
        if (articleId != null){
            articleDto.setId(articleId);
        }
        ResponseResult responseResult = articleClient.saveArticle(articleDto);
        if (responseResult.getCode() != 200){
            throw new RuntimeException("WmNewsAutoScanServiceImpl：article文章保存失败");
        }
        //设置文章服务id
        wmNews.setArticleId((Long) responseResult.getData());
        wmNews.setStatus(WmNews.Status.PUBLISHED.getCode());
        wmNews.setReason("审核通过");
        wmNewsService.updateById(wmNews);

    }

    //单独自有敏感词过滤
    @Async
    @Override
    public void selfSensitiveScan(Integer id) {
        WmNews wmNews = wmNewsService.getById(id);
        if (wmNews == null) {
            throw new RuntimeException("WmNewsAutoScanServiceImpl：文章不存在");
        }
        // 获取文章内容和图片
        Map<String, Object> contentAndPictures = getContentAndPictures(wmNews);

        //光学识别处理图片 tess4j,                            (过滤获得新图片字节数组)未实现
        boolean OCRresult = handlePicturesByTess4j(contentAndPictures,wmNews);
        if (!OCRresult)return;

        //自有敏感词库过滤
        boolean result = selfSensitiveScanFilter((String) contentAndPictures.get("text"),wmNews);
        if (!result){
            return;
        }

        //构建文章数据Dto
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews,articleDto);
        articleDto.setContent(wmNews.getContent());
        articleDto.setAuthorId(wmNews.getUserId().longValue());
        WmUser wmUser = wmUserService.getById(wmNews.getUserId());
        articleDto.setAuthorName(wmUser.getName());
        WmChannel wmChannel = wmChannelService.getById(wmNews.getChannelId());
        articleDto.setChannelName(wmChannel.getName());
        articleDto.setLayout(wmNews.getType());
        articleDto.setCreatedTime(new Date());
        Long articleId = wmNews.getArticleId();
        if (articleId != null){
            articleDto.setId(articleId);
        }
        ResponseResult responseResult = articleClient.saveArticle(articleDto);
        if (responseResult.getCode() != 200){
            throw new RuntimeException("WmNewsAutoScanServiceImpl：article文章保存失败");
        }
        //设置文章服务id
        wmNews.setArticleId((Long) responseResult.getData());
        wmNews.setStatus(WmNews.Status.PUBLISHED.getCode());
        wmNews.setReason("审核通过");
        wmNewsService.updateById(wmNews);

    }

    //处理图片实现
    private boolean handlePicturesByTess4j(Map<String, Object> pictures,WmNews wmNews) {
        List<byte[]> picBytes = getPictureBytesByUrl(pictures);
//        ArrayList<byte[]> newPicList = new ArrayList<>();
        for (byte[] bytes : picBytes){

            //byte[] 转换为bufferedImage
            ByteArrayInputStream in = new ByteArrayInputStream(bytes);
            try {
                BufferedImage bufferedImage = ImageIO.read(in);
                String ocrResult = Tess4jUtils.doOCR(bufferedImage);
                boolean result = selfSensitiveScanFilter(ocrResult, wmNews);
//                if(result){
//                    newPicList.add( bytes);
//                }
                if(!result){
                    return false;
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
//        pictures.put( "pictures", newPicList);
        return true;
    }



    @Autowired
    private WmSensitiveMapper wmSensitiveMapper;
    //自有敏感词库过滤实现
    private boolean selfSensitiveScanFilter(String text, WmNews wmNews) {
        //书库库获取敏感词库
        List<WmSensitive> wmSensitives = wmSensitiveMapper.selectList(Wrappers.<WmSensitive>lambdaQuery().select(WmSensitive::getSensitives));

        //处理敏感词
        List<String> collect = wmSensitives.stream().map(WmSensitive::getSensitives).collect(Collectors.toList());
        //匹配敏感词
        SensitiveWordUtil.initMap(collect);
        Map<String, Integer> map = SensitiveWordUtil.matchWords(text);
        if (!map.isEmpty()){
            wmNews.setStatus(WmNews.Status.FAIL.getCode());
            wmNews.setReason("包含敏感词:" + map);
            wmNewsService.updateById(wmNews);
            return false;
        }
        return true;
    }

    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    FileStorageService fileStorageService;

    private boolean aliAutoScan(Map<String, Object> contentAndPictures, WmNews wmNews) {
        if(contentAndPictures == null && wmNews.getTitle().isEmpty())
            return true;
        boolean flag = true;
        StringBuilder reason = new StringBuilder();
        if (wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())) {
            // 1.审核文本内容，设置文章状态
            try {
                Map map = greenTextScan.greeTextScan(contentAndPictures.get("text").toString() + "-" + wmNews.getTitle());
                if (map.get("suggestion").equals("pass")){
                    wmNews.setStatus(WmNews.Status.SUCCESS.getCode());
                }else if (map.get("suggestion").equals("review")){
                    wmNews.setStatus(WmNews.Status.ADMIN_AUTH.getCode());
                    reason.append("文本人工审核");
//                    wmNews.setReason("文本人工审核");
                    flag = false;
                }else {
                    wmNews.setStatus(WmNews.Status.FAIL.getCode());
                    wmNews.setReason("文本审核未通过");
                    wmNewsService.updateById(wmNews);
                    flag = false;
                    return flag;
                }

            } catch (Exception e) {
                flag = false;
                throw new RuntimeException(e);
            }
            // 2.审核图片内容，设置文章状态
            ArrayList<byte[]> pictureByte = getPictureBytesByUrl(contentAndPictures);
            try {
                Map imageScan = greenImageScan.imageScan(pictureByte);
                if (imageScan.get("suggestion").equals("pass")){
                    wmNews.setStatus(WmNews.Status.SUCCESS.getCode());
                }else if (imageScan.get("suggestion").equals("review")){
                    wmNews.setStatus(WmNews.Status.ADMIN_AUTH.getCode());
                    reason.append("图片人工审核");
                    wmNews.setReason(reason.toString());
                    wmNewsService.updateById(wmNews);
//                    wmNews.setReason("图片人工审核");
                    flag = false;
                    return flag;
                }else {
                    wmNews.setStatus(WmNews.Status.FAIL.getCode());
                    wmNews.setReason("图片审核未通过");
                    wmNewsService.updateById(wmNews);
                    flag = false;
                    return flag;
                }
            } catch (Exception e) {
                flag = false;
                throw new RuntimeException(e);
            }
        }

        return flag;
    }

    private ArrayList<byte[]> getPictureBytesByUrl(Map<String, Object> contentAndPictures) {
        List<String> pictures =(List<String>) contentAndPictures.get("pictures");
        //图片去重
        List<String> collect = pictures.stream().distinct().collect(Collectors.toList());
        ArrayList<byte[]> pictureByte = new ArrayList<>();
        for (String picture : collect) {

            byte[] bytes = fileStorageService.downLoadFile(picture);
            pictureByte.add(bytes);
        }
        return pictureByte;
    }


    private Map<String,Object> getContentAndPictures(WmNews wmNews) {

        String content = wmNews.getContent();
        List<String> pictures = new ArrayList<>();
        StringBuilder contentBuilder = new StringBuilder();
        HashMap<String, Object> textAndPicture = new HashMap<>();
        List<Map> newsContent = JSON.parseArray(content, Map.class);
        for (Map map : newsContent){
            // 2.获取文章图片内容
            if(map.get("type").equals("image")){
                String imgUrl = (String) map.get("value");
                pictures.add(imgUrl);
            }
            // 1.获取文章文本内容
            if(map.get("type").equals("text")){
                 contentBuilder.append(map.get("value"));
            }
        }
        textAndPicture.put("text",contentBuilder.toString());
        String[] coverImages = wmNews.getImages().split(",");
        pictures.addAll(Arrays.asList(coverImages));
        textAndPicture.put("pictures",pictures);

        return textAndPicture;
    }
}
